package cm.android;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import android.R.integer;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import org.json.*;

public class FreeSyn extends ListActivity implements OnItemClickListener{
	public String mServerPath = "192.168.1.101";
	public int mServerPort = 8000;
	public String mHttpServerPath = "http://" + mServerPath + ":" + mServerPort + "/";
	//public String mLoclString = "/sdcard/synatic/";
	public String mLoclString = "/sdcard/";
	
	private ArrayList<String> mSynPath = new ArrayList<String>();
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.main);
        //CheckAndUpdate();
        //UpdateSynConfig();
        ListView lsListView = getListView();
        lsListView.setLongClickable(true);
        
        LoadSynPath();
        UpdateSynUI();
        
        ListView ls = getListView();
        ls.setOnItemClickListener(this);
    }
    
    public static long ST2AT(long lTime) {
    	return (lTime - 3600) * 1000;
    }
    
    public static long AT2ST(long lTime) {
    	return lTime / 1000 + 3600;
    }
    
    private void LoadSynPath() {
    	try {
			FileInputStream fis = openFileInput("synpath");
			mSynPath.clear();
			
			DataInputStream dis = new DataInputStream(fis);
			do {
				String strRead = dis.readLine();
				if (strRead == null)
					break;
				mSynPath.add(strRead);
			}while(true);
			dis.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    private void AddSynPath(String strPath) {
    	mSynPath.add(strPath);
    }
    
    private void DelSynPath(String strPath) {
		mSynPath.remove(strPath);
	}
    
    private void UpdateSynConfig() {
    	try {
			FileOutputStream fos = openFileOutput("synpath", BIND_AUTO_CREATE);
			for (String str : mSynPath) {
				DataOutputStream dos = new DataOutputStream(fos);
				try {
					dos.writeBytes(str + "\r\n");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
        
    private void UpdateSynUI() {
    	//ListView ls = (ListView) findViewById(R.layout.main);
    	ListView ls = getListView();
    	ArrayList<String> info = new ArrayList<String>();
    	ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,info);
    	ls.setAdapter(adapter);
    	
    	info.add(getString(R.string.addpath));
		for (String str : mSynPath) {
			info.add(str);
		}
		adapter.notifyDataSetChanged();
	}
    private void ModifyTime(String filenameString, long PyTime) {
    	File fm = new File(mLoclString + filenameString);
		fm.setLastModified(ST2AT(PyTime));
	}
    
    private HashMap<String, Long> EnumAllPath() {
    	HashMap<String, Long> fileMap = new HashMap<String, Long>();
    	for (String str : mSynPath) {
    		EnumFolder(str, fileMap);
    	}
    	return fileMap;
    }
    
    public void CheckAndUpdate() {
    	String checkString = CheckFiles();
    	if (checkString != null) {
    		//HashMap<String, Long> fileMap = EnumFolder(mLoclString);
    		HashMap<String, Long> fileMap = EnumAllPath();
    		
    		try {
				JSONObject jObject = new JSONObject(checkString);
				Iterator<String> itorIterator = jObject.keys();
				while(itorIterator.hasNext()) {
					String filenameString = itorIterator.next();
					long wTime = jObject.getLong(filenameString);
					if (fileMap.containsKey(filenameString) == false) {
						// 本地没有该文件
						DownLoadFile(filenameString);
						ModifyTime(filenameString, wTime);
					} else {
						long vTime = fileMap.get(filenameString);
						if (vTime < wTime) {
							DownLoadFile(filenameString);
							ModifyTime(filenameString, wTime);
						} else if (vTime > wTime) {
							UpLoadFile(mLoclString + filenameString);
						} else {
							fileMap.remove(filenameString);
						}
					}
				}
				
				Iterator<String> it = fileMap.keySet().iterator();
				while(it.hasNext()) {
					String filenameString = it.next();
					UpLoadFile(mLoclString + filenameString);
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }
    
    public void Test() {
    	System.out.print("ok");
    }
    
    public String FromCardPath(String filename) {
    	String strRootString = "/sdcard/";
    	return filename.substring(strRootString.length(), filename.length());
    }
    
    public String FromWebPath(String filename) {
    	String strWebString = "192.168.1.101:8000";
    	return strWebString;
    }
    
    public HashMap<String, Long> EnumFolder(String strPath) {
    	HashMap<String, Long> filemap = new HashMap<String, Long>();
    	
    	return EnumFolder(strPath, filemap);
    }
    
    private HashMap<String, Long> EnumFolder(String strPath, HashMap<String, Long> InMap) {
    	
    	File file = new File(strPath);
    	File[] files = file.listFiles();
    	
    	if (files != null) {
	    	for (File f : files) {
	    		if (f.isDirectory()) {
	    			InMap.putAll(EnumFolder(f.getAbsolutePath()));
	    		} else {
	    			String fullpath = f.getPath();
	    			String filename = fullpath.substring(mLoclString.length(), fullpath.length());
	    			InMap.put(filename, AT2ST(f.lastModified()));
	    		}
	    	}
    	}
    	
    	return InMap;
    }
    
    
    //从服务器获得最新数据
    public String CheckFiles() {
    	try {
    		URL url = new URL(mHttpServerPath + "check");
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
			conn.setDoInput(true);  
			conn.setConnectTimeout(10000);  
			conn.setRequestMethod("GET");  
			conn.setRequestProperty("accept", "*/*");  
			conn.connect();  
			
			int resCode = conn.getResponseCode();
			if (resCode == 200) {
				int nLen = conn.getContentLength();
				byte[] dat = new byte[nLen];
				
				int nRead = conn.getInputStream().read(dat);
				if (nLen == nRead) {
					return new String(dat);
				}
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return null;
    }
    
    // no full path
    public boolean DownLoadFile(String filename) {
    	try  {  
    		URL url = new URL(mHttpServerPath + filename);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
			conn.setDoInput(true);  
			conn.setConnectTimeout(10000);  
			conn.setRequestMethod("GET");  
			conn.setRequestProperty("accept", "*/*");  
			conn.connect();  

			int resCode = conn.getResponseCode();
			if (resCode == 200) {
				byte[] odat = new byte[4096];
				InputStream isInputStream = conn.getInputStream();
				
				File checkExsit = new File(mLoclString + filename);
				if (checkExsit.exists() == false) {
					checkExsit.getParentFile().mkdirs();
				}
					
				FileOutputStream fos = new FileOutputStream(mLoclString + filename);
				while(true) {
					int len = isInputStream.read(odat);
					if (len == -1)
						break;
					fos.write(odat, 0, len);
				}
				fos.close();
			}
			conn.disconnect();
			return true;
    	} 
    	catch(Exception ee)	{  
			System.out.print("ee:" + ee.getMessage());
		}   
		return false;
	}
    
    // full path
    public boolean UpLoadFile(String filename) {
    	
    	
    	
    	FormFile upfile = new FormFile(filename);
    	if (upfile.exists() == false)
    		return false;
    	
    	StringBuffer post = new StringBuffer(); 
    	post.append("-----------------------------7d33a816d302b6\r\n"); 
    	post.append("Content-Disposition: form-data; name=\"file\"; filename=\"");
    	post.append(FromCardPath(filename));
    	post.append("\"\r\n"); 
    	post.append("Content-Type: application/octet-stream\r\n\r\n");
    	
    	String boundString = "\r\n-----------------------------7d33a816d302b6--\r\n";
    	
    	StringBuffer head = new StringBuffer();
    	head.append("POST / HTTP/1.1\r\n");
    	head.append("Accept: text/plain, */*\r\n");
    	head.append("Accept-Language: zh-cn\r\n");
    	head.append("Host: 192.168.1.101:80\r\n");
    	head.append("Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6\r\n");
    	head.append("User-Agent: ");
    	head.append(AT2ST(upfile.getMTime()));
    	head.append("\r\nContent-Length: ");
    	head.append(upfile.length() + post.length() + boundString.length());
    	head.append("\r\nConnection: Keep-Alive\r\n\r\n");
    	
    	
    	try {
    		
			Socket so = new Socket("192.168.1.101", 8000);
			OutputStream os = so.getOutputStream();
			os.write(head.toString().getBytes());
			os.write(post.toString().getBytes());
			
			if (upfile.CopyToStream(os) == true) {
				os.write(boundString.getBytes());
				os.flush();
				so.close();
				
				Toast.makeText(this, filename + " be Upload!", Toast.LENGTH_LONG).show();
				return true;
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return false;
    }

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		// TODO Auto-generated method stub
		if (arg2 == 0) {
			Intent intent = new Intent();
			intent.setClass(this, EnumFiles.class);
			//startActivity(intent);
			startActivityForResult(intent, 0);
		}
	}
	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if (resultCode == RESULT_OK) {
    		String string = data.getStringExtra("folder");
    		mSynPath.add(string);
    		
    		UpdateSynConfig();
    		UpdateSynUI();
    	}
    }

}